/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package analiseSintatica.Regras.Comandos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;
import java.util.LinkedList;

/**
 *
 * @author Ivo Romário
 */
public class RegraBloco extends Regra{


    protected static Regra instancia;

    protected String estrutura = "<instrucao> | '{' {<instrucao>} '}'";

    

    /**
     * Construtor privado necessario ao singleton
     */
    private RegraBloco() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraBloco getInstance() {
        if (instancia == null) {
            instancia = new RegraBloco();
        }
        return (RegraBloco) instancia;
    }

    

    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {

         ErroSintaticoException erros = new ErroSintaticoException();

         NoArvore naoTerminalBloco = new NoArvore("<bloco>", false);

         
             if(RegraInstrucao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getLexema())||
             RegraInstrucao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getToken())){
                 try{

                     naoTerminalBloco.adicionaFilho(RegraInstrucao.getInstance().analisar(listaTokens));
                 }
                 catch(ErroSintaticoException e){
                 }
             }
             else {
                try{
                    naoTerminalBloco.adicionaFilho(reconheceLexema(listaTokens, "delimitador", "{",estrutura));
                }
                catch(ErroSintaticoException e){
                }
                while(RegraInstrucao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getLexema())){
                    try{
                        naoTerminalBloco.adicionaFilho(RegraInstrucao.getInstance().analisar(listaTokens));
                    }
                    catch(ErroSintaticoException e){
                    }
                }
                try{
                    naoTerminalBloco.adicionaFilho(reconheceLexema(listaTokens, "delimitador", "}",estrutura));
                }
                catch(ErroSintaticoException e){
                }

                
             }
         


         return naoTerminalBloco;
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    
    @Override
    protected void setPrimeiro() {
        //P(bloco) = P(instrucao) U {'{'}
        this.primeiro.add("{");
        this.primeiro.add("char");
        this.primeiro.add("int");
        this.primeiro.add("float");
        this.primeiro.add("boolean");
        this.primeiro.add("identificador");
        this.primeiro.add("if");
        this.primeiro.add("while");
        this.primeiro.add("do");
        this.primeiro.add("return");
        this.primeiro.add("for");
        this.primeiro.add("printf");
        this.primeiro.add("scanf");
        this.primeiro.add("*");
        this.primeiro.add("++");
        this.primeiro.add("--");
        //this.primeiro = getUniao(primeiro, RegraInstrucao.getInstance().getPrimeiro());
    }

    @Override
    protected void setSeguinte() {
        this.seguinte.add("else");
        this.seguinte.add("while");
        this.seguinte.add("}");
        this.seguinte.add("char");
        this.seguinte.add("int");
        this.seguinte.add("float");
        this.seguinte.add("boolean");
        this.seguinte.add("identificador");
        this.seguinte.add("if");
        this.seguinte.add("while");
        this.seguinte.add("do");
        this.seguinte.add("return");
        this.seguinte.add("for");
        this.seguinte.add("printf");
        this.seguinte.add("scanf");
        this.seguinte.add("*");
        this.seguinte.add("++");
        this.seguinte.add("--");
    }

}
